import type { Router } from 'vue-router';
import NProgress from 'nprogress'; // progress bar

import usePermission from '@/hooks/permission';
import { useUserStore, useAppStore } from '@/store';
import { getToken } from '@/utils/auth';
import { appRoutes } from '../routes';
import { WHITE_LIST, NOT_FOUND } from '../constants';
import addUserRoutes from './userRouter'

export default function setupPermissionGuard(router: Router) {
  router.beforeEach(async (to, from, next) => {
    const appStore = useAppStore();
    const userStore = useUserStore();
    const Permission = usePermission();
    const permissionsAllow = Permission.accessRouter(to);
    // 没有token情况
    if (!getToken()) {
      if (to.path === '/login') {
        // 目标路由是登录的路由就不需要重定向了,不然就是登录重定向到登录,陷入死循环了
        next()
      } else {
        // 重定向到登录
        next({ path: '/login', replace: true });
      }
      NProgress.done();
      return;
    }
    // 针对非来自服务端的菜单配置进行处理
    if (!appStore.menuFromServer) {
      // eslint-disable-next-line no-lonely-if
      if (permissionsAllow) next();
      else {
        const destination =
          Permission.findFirstPermissionRoute(appRoutes, userStore.role) ||
          NOT_FOUND;
        next(destination);
      }
      NProgress.done();
      return;
    }
    // 针对来自服务端的菜单配置进行处理
    // Handle routing configuration from the server
    // 根据需要自行完善来源于服务端的菜单配置的permission逻辑
    // Refine the permission logic from the server's menu configuration as needed
    if (to.path === '/login') {
      // 也就是如果登录了又去登录的话就重定向回到首页
      next({ path: '/', replace: true })
      NProgress.done();
      return;
    }
    // 当为白名单页面 直接进入
    if (WHITE_LIST.find((el) => el.name === to.name)) {
      next()
      NProgress.done();
      return;
    }
    // 如果执行了就不需要每次路由跳转的时候去操作了
    if (!appStore.appAddRoute) {
      await addUserRoutes();
      next({ ...to, replace: true })
    }
    if (permissionsAllow) {
      next();
    } else {
      next(NOT_FOUND);
    }
    NProgress.done();
  });

  router.afterEach(()=> {
    NProgress.done();
  })
}
